package cn.tedu.csmallproductzxj.service.impl;

import cn.tedu.csmallproductzxj.ex.ServiceException;
import cn.tedu.csmallproductzxj.mapper.CategoryMapper;
import cn.tedu.csmallproductzxj.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmallproductzxj.pojo.entity.Category;
import cn.tedu.csmallproductzxj.pojo.vo.CategoryListItemVO;
import cn.tedu.csmallproductzxj.pojo.vo.CategoryStandardVO;
import cn.tedu.csmallproductzxj.service.ICategoryService;
import cn.tedu.csmallproductzxj.web.ServiceCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        //名称不允许重复
        String name = categoryAddNewDTO.getName();
        int countByName = categoryMapper.countByName(name);
        if (countByName > 0) {
            String message = "新增类别失败，类别名称已经被占用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        //depth的推导过程：(原理：depth是对象的父级类别+1)
        //先判断父级id是否为0 是0则depth为1 不是0则depth=父级类别+1
        Long parentId = categoryAddNewDTO.getParentId();
        CategoryStandardVO parentCategory = null;
        //parentId=0--->depth=1
        Integer depth = 1;
        if (parentId != 0) {
            //parentId！=0---->根据parentId调用mapper对象的getStandardById()查询她的parentId
            parentCategory = categoryMapper.getStandardById(parentId);
            //-- 判断查询结果是否为null
            if (parentCategory == null) {
                //是-->抛出异常
                String message = "新增类别失败，父级类别不存在！";
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
            } else {
                //否--depth值为父级类别的depth+1
                depth = parentCategory.getDepth() + 1;
            }

        }


        //mapper中需要插入的是实   体类对象，所以先创建一个实体类对象
        //创建category对象
        //将DTO中参数的属性赋值到category对象中
        //将category对象中剩余的属性值补齐 depth:
        //将category对象中剩余的属性值补齐 isParent:
        //调用mapper对象的insert()方法
        // 创建Category对象
        Category category = new Category();
        // 将参数的属性复制到Category对象中
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        // 补全Category对象的属性值：depth >>> 通过以上运算得到
        category.setDepth(depth);
        // 补全Category对象的属性值：isParent >>> 固定为0
        category.setIsParent(0);
        // 调用Mapper对象的insert()方法插入数据
        categoryMapper.insert(category);

        //isParent的原理：（只有有子级才能判断它是父级  ）
        //它是固定为0，仅当添加子级后，会同时更新为1
        // 判断parentId是否不为0，且父级类别的isParent为0
        if (parentId != 0 && parentCategory.getIsParent() == 0) {
            // 是：将父级类别的isParent更新为1
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(1);
            categoryMapper.update(updateParentCategory);
        }
    }

    @Override
    public void delete(Long id) {
//先判断数据是否存在，如果是null，则抛出异常
        CategoryStandardVO currentCategory= categoryMapper.getStandardById(id);
        if(currentCategory == null){
            String message = "删除类别失败，尝试访问的数据不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        //再判断是否有子集，如果有子集，则不能删除
        if(currentCategory.getIsParent()==1){
            String message = "删除类别失败，当前类别仍包含子级类别，不允许删除！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        //此时数据既存在并且没有子集
        // 调用Mapper对象的方法执行删除
        int rows = categoryMapper.deleteById(id);
        if (rows != 1) {
            String message = "删除类别失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        //删除后 需要判断它的父级还有没有其他子集，
        // 如果有其他子集，则依旧是父级，如果没有子集，则isParent需要变成0
        // 调用Mapper对象的countByParentId()统计当前类别的父级类别的子级数量
        // 判断统计结果是否为0，如果是，则更新父级类别的isParent为0
        Long parentId=currentCategory.getParentId();
        int countByParentId=categoryMapper.countByParentId(parentId);
        if(countByParentId == 0){
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(0);//把父级的isParent从1改成0
            rows = categoryMapper.update(updateParentCategory);
            if (rows != 1) {
                String message = "删除类别失败，服务器忙，请稍后再尝试！";
                throw new ServiceException(ServiceCode.ERR_UPDATE, message);
            }
        }
    }

    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
        List<CategoryListItemVO> list = categoryMapper.listByParentId(parentId);
        return list;
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    //俩种状态两个公开的方法，但是实现的时候代码基本相同，所以将实现的代码封装到一个私有的方法中，直接调用即可
    private void updateEnableById(Long id, Integer enable) {
        // 调用Mapper的查询，检查类别是否存在
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        if (currentCategory == null) {
            String message = ENABLE_TEXT[enable] + "类别失败，尝试访问的数据不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前类别的启用状态，如果与参数的目标状态相同，则抛出异常
        if (currentCategory.getEnable() == enable) {
            String message = ENABLE_TEXT[enable] + "类别失败，当前类别已经处于【" + ENABLE_TEXT[enable] + "】状态！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 调用Mapper对象执行修改，更新类别的启用状态
        Category updateCategory = new Category();
        updateCategory.setId(id);
        updateCategory.setEnable(enable);
        int rows = categoryMapper.update(updateCategory);
        if (rows != 1) {
            String message = ENABLE_TEXT[enable] + "类别失败，，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }
}
